package com.wuniutech.notebook

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.JsResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.tencent.smtt.sdk.WebChromeClient
import com.tencent.smtt.sdk.WebView
import pub.devrel.easypermissions.EasyPermissions
import java.io.IOException

class MainActivity : AppCompatActivity() {

    lateinit var webView: WebView

    // 临时存储要导出的数据
    private var jsonDataToExport: String? = null

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) // Java
        requestPermissions()
        webView = findViewById(R.id.note_wv)
        webView.addJavascriptInterface(this, "AndroidInterfaceName") // Kotlin
        webView.settings.javaScriptEnabled = true // 需要启用 DOM Storage API 才能使用 localStorage
        webView.settings.domStorageEnabled = true
        webView.settings.useWideViewPort = true
        webView.settings.loadWithOverviewMode = true
        webView.loadUrl("file:///android_asset/notebook.html")
        webView.webChromeClient = MyWebChromeClient(this)
    }

    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
        } else {
            super.onBackPressed()
        }
    }

    /**
     * 数据导出
     */
    @JavascriptInterface
    fun exportJournalData(jsonData: String) {
        runOnUiThread {
            this.jsonDataToExport = jsonData // 存储要导出的数据
            createDocumentLauncher.launch("journal_backup.json")
        }
    }

    /**
     * 数据导入
     */
    @JavascriptInterface
    fun requestImportData() {
        runOnUiThread {
            openDocumentLauncher.launch(arrayOf("application/json")) // 如果需要指定多种 MIME 类型
        }
    }

    private fun requestPermissions() {
        val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE)
        if (EasyPermissions.hasPermissions(this, *permissions)) {

        } else {
            requestPermissions(permissions, 101)
        }
    }

    // 辅助函数：转义 JavaScript 字符串，防止注入问题
    private fun escapeJavaScriptString(str: String?): String {
        return str?.replace("\\", "\\\\")?.replace("'", "\\'")?.replace("\"", "\\\"")
            ?.replace("\n", "\\n")?.replace("\r", "\\r")?.replace("\t", "\\t") ?: "null"
    }

    // 使用 Activity Result API 处理 SAF 的结果
    private val createDocumentLauncher =
        registerForActivityResult(ActivityResultContracts.CreateDocument("application/json")) { uri: Uri? -> // SAF 文件创建意图的结果回调
            if (uri != null) { // 用户选择了保存位置并创建了文件
                FileUtil.saveDataToUri(this, jsonDataToExport, uri) { result, message ->
                    if (result) {
                        ToastUtil.showShortToast("数据导出成功") // 通知 JavaScript 导出成功
                        webView.evaluateJavascript("exportResult(true, '数据导出成功');", null)
                    } else {
                        ToastUtil.showShortToast("数据导出失败: $message") // 通知 JavaScript 导出失败
                        webView.evaluateJavascript("exportResult(false, '数据导出失败: ${
                            escapeJavaScriptString(message)
                        }');", null)
                    }
                }
            } else { // 用户取消了文件选择
                ToastUtil.showShortToast("文件保存已取消") // 通知 JavaScript 导出失败
                webView.evaluateJavascript("exportResult(false, '文件保存已取消');", null)
            }
        }

    private val openDocumentLauncher =
        registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? -> // SAF 文件打开意图的结果回调
            if (uri != null) { // 用户选择了要导入的文件，Uri 不为 null
                FileUtil.readDataFromUri(this, uri) { result, data, message ->
                    if (result) {
                        ToastUtil.showShortToast("数据读取成功") // 回调 JS 的 receiveImportedData 函数
                        runOnUiThread {
                            val escapedJsonData = escapeJavaScriptString(data)
                            webView.evaluateJavascript("receiveImportedData('${escapedJsonData}');",
                                null)
                        }
                    } else {
                        ToastUtil.showShortToast("数据读取失败: $message")
                        webView.evaluateJavascript("receiveImportedData(null);", null)
                    }
                } // 调用一个新方法来读取数据
            } else { // 用户取消了文件选择，Uri 为 null
                ToastUtil.showShortToast("文件导入已取消") // 通知 JavaScript 导入失败
                runOnUiThread {
                    webView.evaluateJavascript("receiveImportedData(null);", null) // 回调 JS 导入失败
                }
            }
        }


    class MyWebChromeClient(private val context: Context) : WebChromeClient() {

        override fun onJsAlert(p0: WebView?,
            p1: String?,
            p2: String?,
            result: com.tencent.smtt.export.external.interfaces.JsResult?): Boolean {
            AlertDialog.Builder(context).setTitle("确认") // 对话框标题
                .setMessage(p2) // JavaScript 传递的消息
                .setPositiveButton(android.R.string.ok) { dialog, which ->
                    result?.confirm() // 用户点击确定，通知 JavaScript confirm() 返回 true
                }.setNegativeButton(android.R.string.cancel) { dialog, which ->
                    result?.cancel() // 用户点击取消，通知 JavaScript confirm() 返回 false
                }.setOnCancelListener { dialog ->
                    result?.cancel() // 用户取消对话框，通知 JavaScript confirm() 返回 false
                }.create().show() // 返回 true 表示您已经处理了这个对话框，WebView 不会再显示默认对话框
            return true
        }

        // 您可能还需要重写 onJsAlert 和 onJsPrompt
    }
}